package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 提高每次读取的数据量减少实际读写的次数可以提高读写效率
 * <p>
 * 单字节读写是一种随机读写形式
 * 一组一组字节的读写是块读写形式
 */
public class CopyDemo2 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("./WeChat.exe");
        FileOutputStream fos = new FileOutputStream("./WeChat_cp2.exe");
        /*
            块读操作(InputStream定义的方法)
            int read(byte[] data)
            一次性读取给定的字节数组总长度的字节量并存入到数组中，返回值为实际读取到的字节量
            如果返回值为-1则表示读取到了末尾。

            举例:
            文件数据(一共5字节):
            11001101 11110000 00001111 01010101 10101010
            byte[] data = new byte[3];//保存3个字节的数组
            data:[00000000 00000000 00000000]
            第一次读取:
            int d = fis.read(data);//由于数组长度为3，因此一次性读取3个字节
            vvvvvvvv vvvvvvvv vvvvvvvv
            11001101 11110000 00001111 01010101 10101010
            读取后的变化:
            data:[11001101 11110000 00001111]//读取到的数据在数组中
            d:3  //表示的是实际读取到了3个字节

            第二次读取:
            d = fis.read(data);//由于数组长度为3，因此一次性读取3个字节
                                       vvvvvvvv vvvvvvvv
            11001101 11110000 00001111 01010101 10101010 文件末尾了
            读取后的变化:
            data:[01010101 10101010 00001111]//读取到的数据在数组中
                  ^^^^^^^^ ^^^^^^^^ 这两个字节是本次读取到的
            d:2  //表示的是实际读取到了2个字节(意味着data数组只有前2个字节是本次读到的)

            第三次读取:
            d = fis.read(data);//由于数组长度为3，因此一次性读取3个字节
                                                         vvvvvvvv
            11001101 11110000 00001111 01010101 10101010 文件末尾了
            读取后数组没有变化:
            data:[01010101 10101010 00001111]//本次没有读取到任何内容
            d:-1 //-1表示已经是末尾了，没有读取到任何内容!



            块写操作(OutputStream定义的方法)
            void write(byte[] data)
            一次性将给定的字节数组中所有字节写出

            void write(byte[] data,int offset,int len)
            将给定的字节数组从下标offset处开始的连续len个字节一次性写出


         */
        /*
            8位2进制
            00000000    1byte
            1024byte    1kb
            1024kb      1mb
            1024mb      1gb
            1024gb      1tb
         */
        byte[] data = new byte[1024 * 10];//10k
        int d;//记录每次实际读取到的字节数量

        long start = System.currentTimeMillis();
        while ((d = fis.read(data)) != -1) {
            fos.write(data);
        }
        long end = System.currentTimeMillis();
        System.out.println("复制完毕!耗时:" + (end - start) + "ms");
        fis.close();
        fos.close();

    }
}
